﻿#region File and License Information
/*
<File>
	<License>
		Copyright © 2009 - 2017, Daniel Vaughan. All rights reserved.
		This file is part of Calcium (http://calciumsdk.net), 
		which is released under the MIT License.
		See file /Documentation/License.txt for details.
	</License>
	<CreationDate>2009-04-11 21:46:18Z</CreationDate>
</File>
*/
#endregion

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

using Outcoder.IO;
using Outcoder.Resources;
using Outcoder.Services.DialogService;

namespace Outcoder.Services.Implementation
{
	/* TODO: [DV] Comment. */
	public class CommandLineDialogService : DialogService
	{
		readonly ICommandLine commandLine;

		public CommandLineDialogService(ICommandLine commandLine)
		{
			ArgumentValidator.AssertNotNull(commandLine, "commandLine");
			this.commandLine = commandLine;
		}

		public async override Task<DialogResult> ShowDialogAsync(
								object body, string caption,
								DialogButton messageButton, DialogImage dialogImage = DialogImage.None,
								DialogImportance importanceThreshold = DialogImportance.High,
								object details = null,
								DialogController dialogController = null)
		{
			/* If the importance threshold has been specified and it's less than the minimum level required (the filter level) 
			 * then we don't show the message. */
			if (importanceThreshold < MinumumImportance)
			{
				return DialogResult.OK;
			}

			DialogResult result = DialogResult.OK; /* Satisfy compiler with default value. */

			lock (commandLine.SyncLock)
			{
				if (!string.IsNullOrEmpty(caption))
				{
					commandLine.WriteLine(new CommandLineText(caption, CommandLineStyle.Title));
				}

				string bodyString = body != null ? body.ToString() : string.Empty;

				commandLine.WriteLine(new CommandLineText(bodyString, CommandLineStyle.Normal));
				

				List<KeyValuePair<int, string>> menuOptions;
				int selectedOption;

				switch (messageButton)
				{
					/* TODO: add view details option. */

					case DialogButton.OKCancel:
						menuOptions = new List<KeyValuePair<int, string>>
						              	{
						              		new KeyValuePair<int, string>(1, "Ok"),
						              		new KeyValuePair<int, string>(2, "Cancel")
						              	};
						selectedOption = GetSelectedOption(menuOptions);
						result = selectedOption == 1 ? DialogResult.OK : DialogResult.Cancel;
						break;
					case DialogButton.YesNo:
						menuOptions = new List<KeyValuePair<int, string>>
						              	{
						              		new KeyValuePair<int, string>(1, "Yes"),
						              		new KeyValuePair<int, string>(2, "No")
						              	};
						selectedOption = GetSelectedOption(menuOptions);
						result = selectedOption == 1 ? DialogResult.Yes : DialogResult.No;
						break;
					case DialogButton.YesNoCancel:
						menuOptions = new List<KeyValuePair<int, string>>
						              	{
						              		new KeyValuePair<int, string>(1, "Yes"),
						              		new KeyValuePair<int, string>(2, "No"),
						              		new KeyValuePair<int, string>(3, "Cancel")
						              	};
						selectedOption = GetSelectedOption(menuOptions);
						switch (selectedOption)
						{
							case 1:
								result = DialogResult.Yes;
								break;
							case 2:
								result = DialogResult.No;
								break;
							default:
								result = DialogResult.Cancel;
								break;
						}
						break;
					case DialogButton.OK:
						result = DialogResult.OK;
						break;
				}
			}

			return result;
		}

		int GetSelectedOption(List<KeyValuePair<int, string>> menuOptions)
		{
			var validValues = (from menuOption in menuOptions select menuOption.Key).ToList();
			do
			{
				foreach (var menuItem in menuOptions)
				{
					string menuLine = string.Format(StringResources.Services_ConsoleDialogService_MenuItemFormat,
						menuItem.Key, menuItem.Value);
					commandLine.WriteLine(new CommandLineText(menuLine, CommandLineStyle.MenuItem));
				}
				string line = commandLine.ReadLine();
				if (line != null)
				{
					int result;
					if (int.TryParse(line, out result))
					{
						if (validValues.Contains(result))
						{
							return result;
						}
					}
				}
				commandLine.WriteLine(new CommandLineText("Invalid input.", CommandLineStyle.Error)); /* TODO: Make localizable resource. */
			} while (true);
		}
	}
}
